package cn.dkdoo.utils.common;

import cn.dkdoo.utils.utils.DkdSpringUtils;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author nicky
 * @date 2021/5/19 下午12:11
 */
public class ReflectPool {
    public static final Map<String, Method> METHOD_CACHE = new ConcurrentHashMap<>();
    public static final AtomicLong rollBackId = new AtomicLong(1);

    static {

    }

    public static String addMethod(String beanName, String methodName) throws NoSuchMethodException {
        return addMethod(beanName, methodName, null);
    }

    public static String addMethod(String beanName, String methodName, Collection<?> args) throws NoSuchMethodException {
        Object obj = DkdSpringUtils.getBeanByBeanName(beanName);
        return addMethod(obj.getClass(), methodName, args);
    }

    public static String addMethod(Class<?> clazz, String methodName, Collection<?> args) throws NoSuchMethodException {
        String key = getPid() + "_" + clazz.getSimpleName() + "_" + rollBackId.getAndIncrement();
        List<Class<?>> paramTypes = new ArrayList<>();
        for (Object arg : args) {
            paramTypes.add(arg.getClass());
        }
        METHOD_CACHE.put(key, clazz.getMethod(methodName, paramTypes.toArray(new Class<?>[paramTypes.size()])));
        return key;
    }

    public static int getPid() {
        try {
            RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
            String name = runtime.getName(); // format: "pid@hostname"
            return Integer.parseInt(name.substring(0, name.indexOf('@')));
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    public static final Method getMethod(String key) {
        return METHOD_CACHE.get(key);
    }
}
